Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
When attempting to use
CodeEditorLink::with_editor
, in my use-case the callback was never invoked, andwith_editor
would always returnNone
. When printing the value of the link, I saw it did have aSome(...)
in there, so I suspect something was up with the wayRc
/ borrows were used? I tried to understand exactly what's happening, but got lost in theScope
/Rc
/RefCell
soup. Another guess is that theScope
that got stored in theRc<RefCell>
onCodeEditorLink
wasn't actually linked (heh) to the real scope, since it got a copy of theScope
.I'm kinda experimenting my way through a fairly big design space, and I have some experience messing with
Rc
and friends, but I'm completely new to Yew, so I'll document my thought process so you can more easily tell me if / how I'm wrong.See it in action:
Attempt 1
CodeEditorModel
inside anRc<RefCell<Option<CodeEditorModel>>>
. This smart pointer gets cloned to each newCodeEditorLink
(instead of storing some reference to aScope
). This makes it easy to reason about what's going on - exactly the data we need is passed around, and it has a single place of storage.CodeEditorLink
to be passed in, for two reasons:CodeEditorLink
didn't expose a public constructor, and the.0
field is private, so there is in fact no way (AFAICT) to create aCodeEditorLink
. This means the feature ... never worked? I think?ctx.prop()
gives us an &-reference, so to update the data in theCodeEditorLink
passed in via props, we need internal mutability, which complicates things further. Dropping this allows the implementation to be simple, and user code can still store theCodeEditorLink
instance received in theon_editor_created
callback.This however has a drawback: if user code wants to store the
CodeEditorLink
, then (at least in functional components) we kinda enforce double-rendering at startup: there's no clean way of saying "re-render if the link changes, except the first time when I store some specialNone
value in the state". So:Attempt 2
link
propertyCodeEditorModel
into aRefCell
to enable internal mutability (no need for another wrappingRc
)This is close, but there's still double-rendering in some circumstances. The core problem is: we don't have anything in
CodeEditorLink
for a stable comparison across rendering passes, only the reference to the model. Since that changes once the editor is created, theCodeEditorLink
is also considered to have changed.I messed around with a synthetic id, but didn't manage to get the behavior I wanted; ended up using
TextModel
instead to get the text out of the editor.Again, this is not perfect; in particular, if
on_editor_created
depends on theCodeEditorLink
, then we get double-rendering. But I figure it's an improvement still, so submitting the PR.